home *** CD-ROM | disk | FTP | other *** search
Text File | 1994-04-26 | 22.6 KB | 799 lines | [TEXT/PJMM] |
- (************************************************************************)
- (* an example programme for a Photoshop acquisition plug-in *)
- (* by Daniel W. Rickey *)
- (* London, Ontario, CANADA *)
- (* drickey@irus.rri.uwo.ca *)
- (* written in Think Pascal *)
- (* based on an MPW example programme by Thomas Knoll *)
- (* last modified 1994-04-27 *)
- (* *)
- (* Note that this Plug-in assumes that System 7.0 or newer is used *)
- (************************************************************************)
- Unit ExampleAcquisition;
-
- Interface
-
- Uses
- AcquireInterface;
-
- {When a plug-in module is called, Adobe Photoshop opens the resource fork}
- {of the plug-in file, loads the resource into to memory and locks it.}
- {The plug-in is then called starting at the first byte of the resource with the}
- {following calling convention:}
- Procedure Main (selector: Integer; AcquireRecord: AcquireRecordPtr; Var myData: Handle; Var result: Integer);
-
- Implementation
-
- Const
- kAbortAcquisition = 1; {an error occurred or the user selected cancel}
-
- (* the following are key codes to be used in dialogue box filters *)
- kEnterKey = $03;
- kBackSpace = $08;
- kTabKey = $09;
- kReturnKey = $0D;
- kEscKey = $1B;
- kLeftArrow = $1C;
- kRightArrow = $1D;
- kUpArrow = $1E;
- kDownArrow = $1F;
- kDeleteKey = $7F;
-
- (* these are friendly keys and are passed through the filters *)
- kControlKeys = [kBackSpace, kTabKey, kLeftArrow, kRightArrow, kUpArrow, kDownArrow, kDeleteKey];
-
- Type
- {keep all of our variables in one record handle}
- {this will be used instead of keeping global variables}
- myDataType = Record
- Acquire: AcquireRecordPtr;
- Result: Integer;
-
- LastRows: Integer; {keep track of the image size and type}
- LastCols: Integer; {If the plug-in is called more than once, the last}
- LastMode: Integer; {set of parameters will be presented to the user.}
-
- ImageRow: Integer; {Image row being acquired; 1..Number of rows}
- ImagePlane: Integer; {image plane being acquired; 0..3}
- End;
-
- myDataPtr = ^myDataType;
- myDataHand = ^myDataPtr;
-
-
- (**** Calls the host's TestAbort function ****)
- (**** may call this several times a second to allow the user to abort the acquisition ****)
- (**** this also changes the cursor to a watch and periodically moves the watch hands ****)
- Function TestAbort (myData: myDataHand): Boolean;
- Var
- address: ProcPtr;
-
- Function DoTestAbort (codeAddress: ProcPtr): Boolean;
- Inline
- $205F, $4E90;
-
- Begin
- TestAbort := FALSE;
- Exit(TestAbort);
-
- address := myData^^.Acquire^.abortProc;
- TestAbort := DoTestAbort(address);
- End; {TestAbort}
-
-
- (**** Calls the host's UpdateProgress procedure ****)
- (**** The first parameter is the number of operations completed ****)
- (**** the second is the total number of operations to do ****)
- Procedure UpdateProgress (NumberDone, total: LongInt; myData: myDataHand);
- Var
- address: ProcPtr;
-
- Procedure DoUpdateProgress (NumberDone, total: LongInt; CodeAddress: ProcPtr);
- Inline
- $205F, $4E90;
-
- Begin
- address := myData^^.Acquire^.ProgressProc;
- DoUpdateProgress(NumberDone, total, address);
- End; {UpdateProgress}
-
-
- (**** Displays the about dialogue box for the plug-in module. ****)
- Procedure DoAbout;
- Const
- kDialogueID = 16000;
-
- Var
- theDialogueHand: DialogTHndl;
- theDialogue: DialogPtr;
- theItem: Integer;
-
-
- Begin
- {load the dialgue resource into memory and lock it}
- theDialogueHand := DialogTHndl(GetResource('DLOG', kDialogueID));
- HNoPurge(Handle(theDialogueHand));
-
- {get our about dialogue from the resource}
- theDialogue := GetNewDialog(kDialogueID, Nil, WindowPtr(-1));
-
- {display the dialogue and wait for the user to select okay}
- ModalDialog(Nil, theItem);
-
- {get rid of the dialogue window and the resource}
- DisposDialog(theDialogue);
- HPurge(Handle(theDialogueHand))
- End; {DoAbout}
-
-
- (**** Prepare to acquire an image. If the plug-in module needs only a limited ****)
- (**** amount of memory, it can lower the value of the 'maxData' field. ****)
- Procedure DoPrepare (myData: myDataHand);
- Begin
- {Photoshop initialises maxData to the maximum of number of bytes it can free}
- {divide by two to give half to photoshop and half to the plug-in}
- myData^^.Acquire^.maxData := myData^^.Acquire^.maxData Div 2;
- End; {DoPrepare}
-
-
- (**** outlines the OK button in a dialogue box ****)
- (**** this is from the new inside mac, Toolbox essentials ****)
- Procedure OutlineOKbutton (theDialogue: DialogPtr; TheItem: Integer);
- Const
- kOkayButton = 1;
- kButtonFrameInset = -4;
- kButtonFrameSize = 3;
-
- Var
- itemType: Integer;
- itemRect: Rect;
- ItemHandle: Handle;
- CurrentPen: PenState;
- ButtonOval: Integer;
- OldPort: WindowPtr;
- thePattern: Pattern;
-
- Begin
- GetDItem(theDialogue, kOkayButton, itemType, ItemHandle, itemRect);
-
- GetPort(OldPort);
- SetPort(ControlHandle(itemHandle)^^.ContrlOwner);
-
- GetPenState(CurrentPen);
- PenNormal;
- InsetRect(itemRect, kButtonFrameInset, kButtonFrameInset);
- FrameRoundRect(itemRect, 16, 16);
- ButtonOval := (ItemRect.Bottom - ItemRect.Top) Div 2 + 2;
-
- {get the black pen pattern from the system resource}
- GetIndPattern(thePattern, 0, 1);
- {set the pen pattern to black; can not use "Black" since it is an A5 QD global}
- PenPat(thePattern);
-
- PenSize(kButtonFrameSize, kButtonFrameSize);
- FrameRoundRect(itemRect, ButtonOval, ButtonOval);
-
- SetPenState(CurrentPen);
- SetPort(OldPort);
- End; {OutlineOKbutton}
-
-
- (**** filter key strokes function for the image parameters dialogue window ****)
- (**** allows only numbers to be entered in the image width and height text boxes ****)
- Function myImageParametersFilter (theDialogue: DialogPtr; Var TheEvent: EventRecord; Var ItemHit: Integer): Boolean;
- Const
- kDialogueID = 16001;
- kOkayItem = 1;
- kCancelItem = 2;
- kImageWidthItem = 3;
- kImageHeightItem = 4;
-
- kBitMapItem = 5;
- kGreyScaleItem = 6;
- kColourItem = 7;
- kRGBcolourItem = 8;
-
- kOkayOutlineItem = 13;
-
- DefaultItem = kOkayItem;
-
- Var
- Key: Integer;
- TextField: Integer;
-
- Begin
- myImageParametersFilter := FALSE;
-
- (* check if a key was pressed, or an autoRepeat happened *)
- If (TheEvent.What = KeyDown) Or (TheEvent.What = AutoKey) Then
- Begin
- (* check what text field the keystokes are occuring in *)
- TextField := DialogPeek(TheDialogue)^.EditField + 1;
-
- {get the key that was pressed}
- Key := band(TheEvent.Message, CharCodeMask);
-
- {if the key was a control key, or in the range 0 to 9, then do not filter it}
- If (Key In kControlKeys) Or (Key In [Ord('0')..Ord('9')]) Then
- Begin
- myImageParametersFilter := FALSE;
- End
- {if the enter or return key was pressed, then pass back okay button selected}
- Else If Key In [kEnterKey, kReturnKey] Then
- Begin
- myImageParametersFilter := TRUE;
- ItemHit := DefaultItem;
- End
- {if we are in a text field and a non-numeric key is pressed then filter}
- Else If (TextField In [kImageWidthItem, kImageHeightItem]) And Not (Key In [Ord('0')..Ord('9')]) Then
- Begin
- myImageParametersFilter := TRUE;
- End;
-
- End; {If KeyDown}
- End; {myImageParametersFilter}
-
-
- (**** Converts a string to a number between 1 and 30000 ****)
- (**** Returns false if not a valid number or out of range ****)
- Function ConvertString (theString: Str255; Var theNumber: Integer): Boolean;
-
- Var
- Loop: Integer;
- x: LongInt;
-
- Begin
- ConvertString := FALSE;
-
- {loop through all of the characters in the string and make sure all are numbers}
- {we do not really need to do this as the dialogue filter should have filtered}
- {all non-numeric characters}
- For Loop := 1 To Length(theString) Do
- Begin
- If Not (theString[Loop] In ['0'..'9']) Then
- Begin
- EXIT(ConvertString);
- End;
- End;
-
- {convert the string to a long integer}
- StringToNum(theString, x);
-
- {make sure the number is reasonable }
- If (x > 0) And (x < 30001) Then
- Begin
- ConvertString := TRUE;
- theNumber := x;
- End;
-
- End; {ConvertString}
-
-
- (**** Prompt the user for the image parameters; Returns false if the user cancels ****)
- Function GetImageParameters (Var ImageWidth, ImageHeight, mode: Integer): BOOLEAN;
- Const
- kDialogueID = 16001;
- kOkayItem = 1;
- kCancelItem = 2;
- kImageWidthItem = 3;
- kImageHeightItem = 4;
-
- kBitMapItem = 5;
- kGreyScaleItem = 6;
- kColourItem = 7;
- kRGBcolourItem = 8;
-
- kOkayOutlineItem = 13;
-
- Var
- itemRect: Rect;
- WidthString, HeightString: Str255;
- ItemHandle: Handle;
- TheDialogue: DialogPtr;
- TheDialogueHand: DialogTHndl;
- TheItem: Integer;
-
- itemType: Integer;
-
- WidthText: Handle;
- HeightText: Handle;
- bButton: ControlHandle;
- gButton: ControlHandle;
- iButton: ControlHandle;
- cButton: ControlHandle;
-
- Done: Boolean;
-
- Begin
- Done := FALSE;
- {load our dialogue resource into memory to make sure we do not}
- {use another plug-in's dialogue}
- TheDialogueHand := DialogTHndl(GetResource('DLOG', kDialogueID));
- HNoPurge(Handle(TheDialogueHand));
-
- {get our dialogue from the dialogue resource}
- TheDialogue := GetNewDialog(kDialogueID, Nil, WindowPtr(-1));
-
- {get a handle to the "user" button outline item}
- GetDItem(TheDialogue, kOkayOutlineItem, itemType, ItemHandle, itemRect);
-
- {install the drawing routine for the application defined button outline}
- SetDItem(TheDialogue, kOkayOutlineItem, itemType, Handle(@OutlineOKbutton), itemRect);
-
- {set the image height value in the text edit box}
- GetDItem(TheDialogue, kImageHeightItem, itemType, HeightText, itemRect);
- NumToString(ImageHeight, HeightString);
- SetIText(HeightText, HeightString);
-
- {set the image width value in the text edit box}
- GetDItem(TheDialogue, kImageWidthItem, itemType, WidthText, itemRect);
- NumToString(ImageWidth, WidthString);
- SetIText(WidthText, WidthString);
-
- {select all of the text in the Image width text edit box}
- SelIText(TheDialogue, kImageWidthItem, 0, 32767);
-
- Repeat
- {set the states of the four image mode radio-buttons}
- GetDItem(TheDialogue, kBitMapItem, itemType, Handle(bButton), itemRect);
- SetCtlValue(bButton, ORD(mode = acquireModeBitmap));
-
- GetDItem(TheDialogue, kGreyScaleItem, itemType, Handle(gButton), itemRect);
- SetCtlValue(gButton, ORD(mode = acquireModeGrayScale));
-
- GetDItem(TheDialogue, kColourItem, itemType, Handle(iButton), itemRect);
- SetCtlValue(iButton, ORD(mode = acquireModeIndexedColor));
-
- GetDItem(TheDialogue, kRGBcolourItem, itemType, Handle(cButton), itemRect);
- SetCtlValue(cButton, ORD(mode = acquireModeRGBColor));
-
- {wait for the user to select something}
- ModalDialog(@myImageParametersFilter, theItem);
-
- Case theItem Of
- kBitMapItem:
- Begin
- mode := acquireModeBitmap;
- End;
- kGreyScaleItem:
- Begin
- mode := acquireModeGrayScale;
- End;
- kColourItem:
- Begin
- mode := acquireModeIndexedColor;
- End;
- kRGBcolourItem:
- Begin
- mode := acquireModeRGBColor;
- End;
-
- kOkayItem: {user selected okay button or pressed the return key}
- Begin
- {get both the image width and image height strings from the text edit boxes}
- GetIText(WidthText, WidthString);
- GetIText(HeightText, HeightString);
-
- {convert the width and height strings to numbers}
- {if an error then beep & select the offending text}
- If Not ConvertString(WidthString, ImageWidth) Then
- Begin
- SelIText(TheDialogue, kImageWidthItem, 0, 32767);
- SysBeep(1);
- End
- Else If Not ConvertString(HeightString, ImageHeight) Then
- Begin
- SelIText(TheDialogue, kImageHeightItem, 0, 32767);
- SysBeep(1);
- End
- Else
- Begin
- {if there were no errors, then return true and exit the loop}
- GetImageParameters := TRUE;
- Done := TRUE;
- End;
- End;
-
- kCancelItem:
- Begin
- {user selected cancel, so exit and return a false value}
- GetImageParameters := FALSE;
- Done := TRUE;
- End;
-
- Otherwise
- Begin
- End;
- End; {Case theItem}
-
- Until Done;
-
- {get rid of our dialogue window}
- DisposDialog(TheDialogue);
-
- {remove our dialogue resource from memory}
- HPurge(Handle(TheDialogueHand));
- End; {GetImageParameters}
-
-
- (**** Asks the user and the returns the image parmaters to the calling program ****)
- (**** This call lets Photoshop know the mode, size and resolution of the image ****)
- (**** being returned, so Photoshop can allocate and initialise its data structures ****)
- (* The plug-in will display the dialogue box during this call and set the ****)
- (**** imageMode, imageSize,depth, planes, imageHRes and imageVRes fields. ****)
- (**** For an indexed color image, the redLUT , greenLUT and blueLUT fields are set ****)
- (**** If a duotone mode image is being acquired, the duotoneInfo field is set ****)
- Procedure DoStart (myData: myDataHand);
- Var
- j: Integer;
-
- Begin
-
- With myData^^, myData^^.Acquire^ Do
- Begin
-
- imageSize.v := LastRows;
- imageSize.h := LastCols;
- imageMode := LastMode;
-
- (* get the image size and mode from the user; exit if canceled *)
- If Not GetImageParameters(imageSize.v, imageSize.h, imageMode) Then
- Begin
- Result := kAbortAcquisition;
- Exit(DoStart)
- End;
-
- (* keep track of the user's choices for next time this is called *)
- LastRows := imageSize.v;
- LastCols := imageSize.h;
- LastMode := imageMode;
-
- (* start with image plane 0; = red for RGB images *)
- ImagePlane := 0;
-
- (* start with the first row of the image plane *)
- ImageRow := 1;
-
- (* initialise the host's image parameter record with appropriate values *)
- Case ImageMode Of
- acquireModeBitmap:
- Begin
- Depth := 1; (* 1 Bit per sample/pixel *)
- Planes := 1; (* 1 sample per pixel *)
- imageHRes := FixRatio(300, 1); (* 300 Horizontal Pixels per inch *)
- imageVRes := FixRatio(300, 1); (* 300 Vertical Pixels per inch *)
- End;
-
- acquireModeGrayScale:
- Begin
- Depth := 8; (* 8 Bits per sample/pixel *)
- Planes := 1; (* 1 sample per pixel *)
- imageHRes := FixRatio(72, 1); (* 72 Horizontal Pixels per inch *)
- imageVRes := FixRatio(72, 1); (* 72 Vertical Pixels per inch *)
- End;
-
- acquireModeIndexedColor:
- Begin
- Depth := 8;
- Planes := 1;
- imageHRes := FixRatio(72, 1);
- imageVRes := FixRatio(72, 1);
-
- {initialise the Look-Up-Tables that are used for indexed colours only}
- {the following is an arbitrary colour LUT}
- For j := 0 To 255 Do
- Begin
- redLUT[j] := CHR(j);
- greenLUT[j] := CHR(255 - j);
- blueLUT[j] := CHR(j Div 2)
- End;
- End;
-
- acquireModeRGBColor:
- Begin
- Depth := 8;
- Planes := 3;
- imageHRes := FixRatio(72, 1);
- imageVRes := FixRatio(72, 1);
- End;
-
- acquireModeCMYKColor:
- Begin
- End;
-
- acquireModeHSLColor:
- Begin
- End;
-
- acquireModeHSBColor:
- Begin
- End;
-
- acquireModeMultichannel:
- Begin
- End;
-
- acquireModeDuotone:
- Begin
- End;
-
- Otherwise
- Begin
- Result := kAbortAcquisition;
- End;
- End; {Case ImageMode}
-
- End; {With}
- End; {DoStart}
-
-
- (**** This call returns a strip of the image to Photoshop. ****)
- (**** Photoshop will continue to call this routine until an error is returned ****)
- (**** or the data field is set to Nil.*)
- Procedure DoContinue (myData: myDataHand);
- Var
- TheStripPtr: Ptr;
- aRow: LongInt;
- aColumn: LongInt;
- RowsInStrip: LongInt;
-
- Begin
-
- With myData^^, myData^^.Acquire^ Do
- Begin
-
- {if any data is left from the previous call, dispose of it}
- If data <> Nil Then
- Begin
- DisposPtr(data);
- data := Nil
- End;
-
- (* the plug-in returns the image data in the "data" field of the acquisition record *)
- (* the image can be returned in many strips; maximum strip size is set by "maxData" *)
- (* The area of the image strip being returned is specified by theRect and by the loPlane and hiPlane fields. *)
-
- (* the byte spacing between columns; we will send each image plane separately *)
- colBytes := 1;
-
- (* this is the number of bytes in one image row, i.e., the byte spacing between rows *)
- If depth = 8 Then
- Begin
- rowBytes := imageSize.h
- End
- Else
- Begin
- rowBytes := BSR(imageSize.h + 7, 3);
- End;
-
- (* determine the maximum number of image rows that can fit into a strip *)
- RowsInStrip := maxData Div rowBytes;
-
- {make sure the size of a single row is not larger than the biggest strip buffer}
- If RowsInStrip < 1 Then
- Begin
- Result := memFullErr;
- EXIT(DoContinue)
- End;
-
- (* acquire/generate image data for all image planes *)
- If ImagePlane < planes Then
- Begin
- {tell the host what image plane is being returned; RGB images are one colour per plane}
- loPlane := ImagePlane;
- hiPlane := ImagePlane;
-
- (* make sure that the rows in the strip is not larger than the remaining image *)
- If RowsInStrip > (imageSize.v - ImageRow + 1) Then
- Begin
- RowsInStrip := imageSize.v - ImageRow + 1;
- End;
-
- (* allocate memory for the image strip *)
- data := NewPtrClear(RowsInStrip * rowBytes);
-
- (* check if the memory was allocated properly *)
- If data = Nil Then
- Begin
- Result := memFullErr;
- Exit(DoContinue)
- End;
-
- (* position and size of the image strip; Photoshop starts at zero thus the "-1" *)
- SetRect(theRect, 0, ImageRow - 1, imageSize.h, ImageRow + RowsInStrip - 1);
-
- (* have our pointer point to the start of the image strip memory *)
- TheStripPtr := data;
-
- (* loop through all of the rows in the image strip *)
- For aRow := ImageRow To ImageRow + RowsInStrip - 1 Do
- Begin
-
- (* check if the user has pressed command-period; exit if true *)
- If TestAbort(myData) Then
- Begin
- Result := kAbortAcquisition;
- Exit(DoContinue)
- End;
-
- {tell the host to update its progress bar}
- UpdateProgress(ImagePlane * ORD4(imageSize.v) + aRow, planes * ORD4(imageSize.v), myData);
-
- (* This is where values are assigned to the pixels in the image. *)
- (* One would normally read in an image from disc or a scanner or just*)
- (* generate a pretty picture using fractals or what-ever. *)
- (* Here we just generate a pretty picture. *)
- {$PUSH}
- {$R-}
- Case ImageMode Of
- {for a bitmapped image, set the values of 8 pixels at once}
- acquireModeBitmap:
- Begin
- (* loop through all bytes in one row of the image strip *)
- For aColumn := 0 To rowBytes - 1 Do
- Begin
- TheStripPtr^ := BSL($FF, BAND(aRow, 7));
- (* point to the next byte in the image strip *)
- TheStripPtr := Ptr(ORD4(TheStripPtr) + 1);
- End; {For aColumn}
- End; {acquireModeBitmap}
-
- {place one byte in each pixel; only have one image plane to worry about}
- acquireModeGrayScale:
- Begin
- (* loop through all bytes/pixels in one row of the image strip *)
- For aColumn := 0 To rowBytes - 1 Do
- Begin
- TheStripPtr^ := BAND(aColumn + aRow, $FF);
- (* point to the next byte in the image strip *)
- TheStripPtr := Ptr(ORD4(TheStripPtr) + 1);
- End; {For aColumn}
- End; {acquireModeGrayScale}
-
- {place one byte in each pixel; only have one image plane to worry about}
- acquireModeIndexedColor:
- Begin
- (* loop through all bytes/pixels in one row of the image strip *)
- For aColumn := 0 To rowBytes - 1 Do
- Begin
- TheStripPtr^ := BAND(aRow + aColumn, $FF);
- (* point to the next byte in the image strip *)
- TheStripPtr := Ptr(ORD4(TheStripPtr) + 1);
- End; {For aColumn}
- End; {acquireModeIndexedColor}
-
- {for an RGB image, place different values in each of the 3 image planes}
- acquireModeRGBColor:
- Begin
- (* loop through all bytes/pixels in one row of the image strip *)
- For aColumn := 0 To rowBytes - 1 Do
- Begin
- Case ImagePlane Of
- 0:
- TheStripPtr^ := BAND(aColumn, $FF);
- 1:
- TheStripPtr^ := BAND(aRow - 1, $FF);
- 2:
- TheStripPtr^ := BAND(aRow - 1 + aColumn, $FF);
-
- Otherwise
- Begin
- End;
- End; {Case ImagePlane}
-
- (* point to the next byte in the image strip *)
- TheStripPtr := Ptr(ORD4(TheStripPtr) + 1);
- End; {For aColumn}
- End; {acquireModeRGBColor}
-
- Otherwise
- Begin
- Result := kAbortAcquisition;
- End;
- End; {Case ImageMode}
-
- {$POP}
- End; {For aRow}
-
- {move to the start of the next image strip}
- ImageRow := ImageRow + RowsInStrip;
-
- {if we have reached the end of an image plane then move onto the next image plane}
- If ImageRow > imageSize.v Then
- Begin
- ImageRow := 1;
- ImagePlane := ImagePlane + 1
- End;
-
- End; {If ImagePlane}
- End; {With}
- End; {DoContinue}
-
-
- (**** This routine will always be called if DoStart does not return an error ****)
- (**** even if DoContinue returns an error or the user aborts the operation ****)
- (**** This allows the Plug-In to delete the image strip buffer ****)
- Procedure DoFinish (Var myData: myDataHand);
- Begin
- {if the image strip data buffer is not empty, then delete it}
- If myData <> Nil Then
- Begin
- With myData^^.Acquire^ Do
- If data <> Nil Then
- Begin
- DisposPtr(data);
- data := Nil
- End;
- End;
- End; {DoFinish}
-
-
- (**** Main dispatching routine. Initialises and sets up the record variables,****)
- (**** and performs the operation specified by the host's selector. ****)
- (**** Think pascal wants this to be called "Main" to be placed first in the resource. ****)
- (**** other development systems may require that this be the first routine in the source code ****)
- Procedure Main (selector: Integer; AcquireRecord: AcquireRecordPtr; Var myData: Handle; Var result: Integer);
-
- Begin
- result := NoErr;
-
- { See if this is the first time called }
- {If so, allocate and initialise the record handle for our variables}
- If (myData = Nil) Then
- Begin
- {allocate memory for our record}
- myData := NewHandleClear(SizeOf(myDataType));
-
- {check if the memory allocation was successful}
- If myData = Nil Then
- Begin
- result := MemFullErr;
- Exit(Main);
- End;
-
- { Initialize our plug-in values }
- myDataHand(myData)^^.LastRows := 256;
- myDataHand(myData)^^.LastCols := 256;
- myDataHand(myData)^^.LastMode := acquireModeRGBColor
- End;
-
- {lock the handle just to be certain}
- HLock(myData);
-
- {keep track of the pointer to the AcquireRecord}
- myDataHand(myData)^^.Acquire := AcquireRecord;
-
- {no error - yet}
- myDataHand(myData)^^.Result := noErr;
-
- {perform the requested action}
- Case selector Of
-
- acquireSelectorAbout: {show the about dialogue}
- DoAbout;
-
- acquireSelectorPrepare: {set things up for acquisition}
- DoPrepare(myDataHand(myData));
-
- acquireSelectorStart: {get parameters from the user}
- DoStart(myDataHand(myData));
-
- acquireSelectorContinue: {acquire or produce the image}
- DoContinue(myDataHand(myData));
-
- acquireSelectorFinish: {tidy things up before modual is disposed of}
- DoFinish(myDataHand(myData));
-
- Otherwise
- myDataHand(myData)^^.Result := acquireBadParameters
-
- End; {Case selector}
-
- {return the result of the request}
- result := myDataHand(myData)^^.Result;
-
- {unlock the handle before returning to the host programme}
- HunLock(myData);
- End; {Main}
-
- End.